#include "Street.hpp"

Street::Street()
{
	m_distance = 500.0f;
	m_numLanes = 2;
    m_texture = getTexture( ":/textures/street.jpg" );
	m_shader = ShaderLibrary::get( "defaultShader" );
	
}


void Street::generate( Random &r )
{
	m_numLanes = r.next( 3 );
	m_x_aligned = r.next(1);
	m_distance = 100.0f;
	setPosition( r.doubleNext(50)-25.0, 0, r.doubleNext(50)-25.0 );
}

void Street::setXAligned( bool aligned )
{
	m_x_aligned = aligned;
}


void Street::setPosition( float x, float y, float z )
{
	m_x = x;
	m_y = y;
	m_z = z;
}


void Street::drawSimple()
{
	draw();
}

void Street::drawShadow()
{
	float laneWidth = 1.7f;
	float width = float(m_numLanes)*laneWidth;
	
	glPushMatrix();
	glTranslatef( m_x, m_y, m_z );
	
	glBegin( GL_QUADS );
	
	if( m_x_aligned )
	{
		glVertex3f( m_distance/2.0f, 0,   -width/2.0f );
		glVertex3f( -m_distance/2.0f, 0,  -width/2.0f );
		glVertex3f( -m_distance/2.0f, 0,  width/2.0f );
		glVertex3f(  m_distance/2.0f, 0,  width/2.0f );
	}
	else
	{
		glVertex3f(  width/2.0f, 0, -m_distance/2.0f );
		glVertex3f( -width/2.0f, 0, -m_distance/2.0f );
		glVertex3f( -width/2.0f, 0, m_distance/2.0f );
		glVertex3f(  width/2.0f, 0, m_distance/2.0f );
	}
	glEnd();
	glPopMatrix();
}

void Street::draw()
{
	GLenum errCode;
	float laneWidth = 1.7f;
	float width = float(m_numLanes)*laneWidth;

	assert( glGetError() == GL_NO_ERROR );
	


	if( m_texture )
	{
		m_texture->bind();
		assert( glGetError() == GL_NO_ERROR );
	}
	
	if( m_shader )
	{
		m_shader->bind();
		assert( glGetError() == GL_NO_ERROR );
	}
	
	
	glPushMatrix();
	assert( glGetError() == GL_NO_ERROR );
	
	glTranslatef( m_x, m_y, m_z );
	assert( glGetError() == GL_NO_ERROR );
	

	glColor3f( 1, 1, 1 );
	
	glBegin( GL_QUADS );
	errCode = glGetError();
	if (errCode != GL_NO_ERROR)
	{
		std::string errString = (const char*)gluErrorString(errCode);
        Logger::write( "Street", "draw() @ 1", errString.c_str(), Logger::Error );
	}
	
	
	
	
	if( m_x_aligned )
	{
		glNormal3f( 0, 1, 0 );
		glTexCoord2f( 0, 40 );
		glVertex3f( m_distance/2.0f, 0,   -width/2.0f );
		glTexCoord2f( 0, 0 );
		glVertex3f( -m_distance/2.0f, 0,  -width/2.0f );

		glTexCoord2f( m_numLanes/2.0, 0 );
		glVertex3f( -m_distance/2.0f, 0,  width/2.0f );

		glTexCoord2f( m_numLanes/2.0, 40 );
		glVertex3f(  m_distance/2.0f, 0,  width/2.0f );
	}
	else
	{
		glNormal3f( 0, 1, 0 );
		glTexCoord2f( m_numLanes/2.0, 0 );
		glVertex3f(  width/2.0f, 0, -m_distance/2.0f );

		glTexCoord2f( 0, 0 );
		glVertex3f( -width/2.0f, 0, -m_distance/2.0f );

		glTexCoord2f( 0, 40 );
		glVertex3f( -width/2.0f, 0, m_distance/2.0f );
		
		glTexCoord2f( m_numLanes/2.0, 40 );
		glVertex3f(  width/2.0f, 0, m_distance/2.0f );
	}
	assert( glGetError() == GL_NO_ERROR );	
	
	glEnd();
	errCode = glGetError();
	if (errCode != GL_NO_ERROR)
	{
		std::string errString = (const char*)gluErrorString(errCode);
        Logger::write( "Street", "draw() @ 2", errString.c_str(), Logger::Error );
	}	

	
	glPopMatrix();

	errCode = glGetError();
	if (errCode != GL_NO_ERROR)
	{
		std::string errString = (const char*)gluErrorString(errCode);
        Logger::write( "Street", "draw() @ 3", errString.c_str(), Logger::Error );
	}
	
	
	
	if( m_texture )
		m_texture->unbind();
	
	if( m_shader )
		m_shader->unbind();	
}
